home *** CD-ROM | disk | FTP | other *** search
- (*=========================================================================*)
- (* Monitor conversion for BPQ-HOST *)
- (* *)
- (* Copyright 1986, 1987, 1991 by H. Roy Engehausen. All rights reserved. *)
- (* *)
- (*=========================================================================*)
-
- {$UNDEF DEBUG_MON1}
- {$UNDEF DEBUG_MON2} (* Used to decipher BPQ stuff *)
-
- PROCEDURE bpq_monitor_convert;
-
- TYPE
- ax25_call_str = STRING[9];
-
- VAR
- address_ptr : address_area_ptr_type;
- address_overptr : ^address_over ABSOLUTE address_ptr;
- c_byte : BYTE;
- c_char : CHAR;
- control_ptr : ^control_field;
- control_string : STRING[10];
- cvt_string : STRING[10];
- data_len : WORD;
- data_ovr : RECORD
- data_ofs : WORD;
- data_seg : WORD;
- END;
- data_ptr : POINTER ABSOLUTE data_ovr;
- data_str : ^STRING ABSOLUTE data_ovr;
- digi_count : BYTE;
- i : BYTE;
- pid_ptr : ^pid_field;
- pid_present : BOOLEAN;
- start_offset : WORD;
- test_byte : BYTE;
-
- (*=========================================================================*)
- (* Translate a AX25 callsign to printable characters *)
- (*=========================================================================*)
-
- FUNCTION ax25_call(in_call : address_field) : ax25_call_str;
-
- (*-----------------------------------------------------------------------*)
- (* Local variables *)
- (*-----------------------------------------------------------------------*)
-
- VAR
- i : BYTE;
- out_call : ax25_call_str;
-
- BEGIN;
-
- (*---------------------------------------------------------------------*)
- (* Loop around printing the characters one by one. Skip blanks *)
- (* Don't forget we have to right shift it one bit....... *)
- (*---------------------------------------------------------------------*)
-
- i := 1;
-
- WHILE (i <= 6) AND (ORD(in_call.name[i]) <> (ORD(' ') * 2)) DO
- BEGIN;
- out_call[i] := CHR(ORD(in_call.name[i]) SHR 1);
- INC(i);
- END;
-
- (*---------------------------------------------------------------------*)
- (* Set the output string length *)
- (*---------------------------------------------------------------------*)
-
- out_call[0] := CHR(i - 1);
-
- (*---------------------------------------------------------------------*)
- (* Now see what the SSID is *)
- (*---------------------------------------------------------------------*)
-
- i := (in_call.addr_flag AND flag_ssid) SHR flag_ssid_shift;
-
- (*---------------------------------------------------------------------*)
- (* If the SSID is not zero, display it too! *)
- (*---------------------------------------------------------------------*)
-
- IF i <> 0 THEN
- BEGIN;
-
- out_call := out_call + '-';
-
- IF i > 9 THEN
- BEGIN;
- i := i - 10;
- out_call := out_call + '1';
- END;
-
- i := ORD('0') + i;
- out_call := out_call + CHR(i);
-
- END;
-
- (*---------------------------------------------------------------------*)
- (* Set the function result and leave *)
- (*---------------------------------------------------------------------*)
-
- ax25_call := out_call;
-
- END; (*----- End subroutine to get AX25 call ----------------------------*)
-
- BEGIN;
-
- active_tcb^.tnc_type := t_to_h_mh_noi;
-
- (*-----------------------------------------------------------------------*)
- (* Point to data area *)
- (*-----------------------------------------------------------------------*)
-
- data_ptr := POINTER(active_tcb^.tnc_tth);
-
- {$IFDEF DEBUG_MON1}
- dump_hex(data_ptr, tnc_registers.CX);
- {$ENDIF}
-
- {$IFDEF DEBUG_MON2}
- move(data_ptr^, control_string[1], 5);
- control_string[0] := CHR(5);
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Remove KISS header after we get the port number out of it *)
- (*-----------------------------------------------------------------------*)
-
- c_char := CHR((ORD(data_str^[2]) AND $0F) + ORD('0'));
-
- INC(data_ovr.data_ofs, 5);
- start_offset := data_ovr.data_ofs;
-
- address_ptr := data_ptr;
-
- {$IFDEF DEBUG_MON1}
- dump_hex(address_ptr, tnc_registers.CX);
- {$ENDIF}
-
- IF tnc_registers.CX < 6 THEN
- EXIT;
-
- DEC(tnc_registers.CX, 5);
-
- (*-----------------------------------------------------------------------*)
- (* Compute digipeater count *)
- (*-----------------------------------------------------------------------*)
-
- digi_count := 0;
- i := address_ptr^.source.addr_flag AND flag_e;
-
- WHILE i = 0 DO
- BEGIN;
-
- (*-------------------------------------------------------------------*)
- (* Count the digipeater. If now invalid # then die *)
- (*-------------------------------------------------------------------*)
-
- INC(digi_count);
- IF digi_count > max_ax25_digipeaters THEN
- BEGIN;
- WRITELN('Bad digicount --', digi_count);
- dump_hex(address_ptr, 255);
- EXIT;
- END;
-
- (*-------------------------------------------------------------------*)
- (* Test to see if last *)
- (*-------------------------------------------------------------------*)
-
- WITH address_ptr^.repeaters[digi_count] DO
- i := addr_flag AND flag_e;
-
- END; (*----- End digipeater address loop ------------------------------*)
-
- (*-----------------------------------------------------------------------*)
- (* Get more info we need *)
- (*-----------------------------------------------------------------------*)
-
- control_ptr := ADDR(address_overptr^[digi_count+3]);
- c_byte := control_ptr^ AND control_su;
-
- (*-----------------------------------------------------------------------*)
- (* Build header -- Destination and source *)
- (*-----------------------------------------------------------------------*)
-
- data_place.data_ptr^.str_data :=
- {$IFDEF DEBUG_MON2}
- c2x(control_string) +
- {$ENDIF}
- c_char +
- ':fm ' + ax25_call(address_ptr^.source) +
- ' to ' + ax25_call(address_ptr^.dest);
-
- (*-----------------------------------------------------------------------*)
- (* Build header -- Repeater addresses *)
- (*-----------------------------------------------------------------------*)
-
- IF digi_count > 0 THEN
- BEGIN;
-
- data_place.data_ptr^.str_data :=
- data_place.data_ptr^.str_data + ' via';
-
- i := 0;
-
- WHILE i < digi_count DO
- BEGIN;
- i := i + 1;
- data_place.data_ptr^.str_data :=
- data_place.data_ptr^.str_data + ' ' +
- ax25_call(address_ptr^.repeaters[i]);
- test_byte := address_ptr^.repeaters[i].addr_flag AND flag_h;
- IF test_byte <> 0 THEN
- data_place.data_ptr^.str_data :=
- data_place.data_ptr^.str_data + '*';
- END;
-
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Build header -- Control field *)
- (*-----------------------------------------------------------------------*)
-
- pid_present := FALSE;
-
- test_byte := control_ptr^ AND NOT control_pf;
-
- CASE c_byte OF
-
- (*---------------------------------------------------------------------*)
- (* I Frame *)
- (*---------------------------------------------------------------------*)
-
- control_if1, control_if2:
- BEGIN;
-
- IF (active_port^.mon_filter AND bpq_monitor_i) = 0 THEN
- BEGIN;
- active_tcb^.tnc_data.long_length := 0;
- EXIT;
- END;
-
- pid_present := TRUE;
- control_string := 'Iab';
- i := (test_byte AND control_nr) SHR control_nr_shift;
- control_string[2] := CHR(i + ORD('0'));
- i := (test_byte AND control_ns) SHR control_ns_shift;
- control_string[3] := CHR(i + ORD('0'));
-
- END;
-
- (*---------------------------------------------------------------------*)
- (* S Frame *)
- (*---------------------------------------------------------------------*)
-
- control_sf:
- BEGIN;
-
- IF (active_port^.mon_filter AND bpq_monitor_s) = 0 THEN
- BEGIN;
- active_tcb^.tnc_data.long_length := 0;
- EXIT;
- END;
-
- i := (test_byte AND control_nr) SHR control_nr_shift;
- control_string := CHR(i + ORD('0'));
- test_byte := test_byte AND control_sm;
- CASE test_byte OF
- control_rr:
- control_string := 'RR' + control_string;
- control_rnr:
- control_string := 'RNR' + control_string;
- control_rej:
- control_string := 'REJ' + control_string;
- ELSE
- control_string := '?S' + b2x(control_ptr^);
- END;
-
- END;
-
- (*---------------------------------------------------------------------*)
- (* U Frame *)
- (*---------------------------------------------------------------------*)
-
- control_uf:
- BEGIN;
-
- test_byte := test_byte AND NOT control_pf;
-
- CASE test_byte OF
- control_ui:
- BEGIN;
-
- IF (active_port^.mon_filter AND bpq_monitor_ui) = 0 THEN
- BEGIN;
- active_tcb^.tnc_data.long_length := 0;
- EXIT;
- END;
-
- control_string := 'UI';
- pid_present := TRUE;
-
- END;
- control_dm:
- control_string := 'DM';
- control_sabm:
- control_string := 'SABM';
- control_disc:
- control_string := 'DISC';
- control_ua:
- control_string := 'UA';
- control_frmr:
- control_string := 'FRMR';
- ELSE
- control_string := '?U' + b2x(control_ptr^);
- END;
-
- IF (control_string <> 'UI')
- AND ((active_port^.mon_filter AND bpq_monitor_s) = 0) THEN
- BEGIN;
- active_tcb^.tnc_data.long_length := 0;
- EXIT;
- END;
-
- END; (*----- End of UI frames ---------------------------------------*)
-
- END; (*----- End of control frame type case statement -------------------*)
-
- data_place.data_ptr^.str_data := data_place.data_ptr^.str_data
- + ' ctl ' + control_string;
-
- (*-----------------------------------------------------------------------*)
- (* Build header -- p/f version *)
- (* We are going to append 1 character that indicates the *)
- (* state of the poll/final flag, the version flag, and the *)
- (* command response state. We will load i with a number *)
- (* 3 bits long which correspond to the settings of each *)
- (* of the 3 bits tested. *)
- (*-----------------------------------------------------------------------*)
-
- test_byte := control_ptr^ AND control_pf;
-
- IF test_byte <> 0 THEN
- i := 1
- ELSE
- i := 0;
-
- test_byte := address_ptr^.source.addr_flag AND flag_c;
-
- IF test_byte <> 0 THEN
- i := i OR $02;
-
- test_byte := address_ptr^.dest.addr_flag AND flag_c;
-
- IF test_byte <> 0 THEN
- i := i OR $04;
-
- CASE i OF
- 0, 6: c_char := ' '; (* Ver 1 w/o p/f *)
- 1, 7: c_char := '.'; (* Ver 1 with p/f *)
- 2 : c_char := 'v'; (* Ver 2 response w/o p/f *)
- 3 : c_char := '-'; (* Ver 2 response with p/f *)
- 4 : c_char := '^'; (* Ver 2 command w/o p/f *)
- 5 : c_char := '+'; (* Ver 2 command with p/f *)
- END;
-
- data_place.data_ptr^.str_data := data_place.data_ptr^.str_data + c_char;
-
- (*-----------------------------------------------------------------*)
- (* Build header -- PID.. Also figure where the data area starts *)
- (*-----------------------------------------------------------------*)
-
- i := OFS(control_ptr^) + SIZEOF(control_field);
- pid_ptr := PTR(SEG(control_ptr^), i);
-
- IF pid_present THEN
- BEGIN;
- IF (i - start_offset) < tnc_registers.CX THEN
- BEGIN;
-
- CASE pid_ptr^ OF
- $F0: i := bpq_monitor_F0;
- $CF: i := bpq_monitor_CF;
- ELSE
- i := bpq_monitor_other;
- END;
-
- IF (active_port^.mon_filter AND i) = 0 THEN
- BEGIN;
- active_tcb^.tnc_data.long_length := 0;
- EXIT;
- END;
-
- data_place.data_ptr^.str_data := data_place.data_ptr^.str_data
- + ' pid ' + b2x(pid_ptr^);
-
- END
- ELSE
- data_place.data_ptr^.str_data := data_place.data_ptr^.str_data
- + ' pid ??';
- i := OFS(pid_ptr^) + SIZEOF(pid_field);
- data_ptr := PTR(SEG(control_ptr^), i);
- END
- ELSE
- data_ptr := ADDR(pid_ptr^);
-
- (*-----------------------------------------------------------------------*)
- (* Compute the data length *)
- (*-----------------------------------------------------------------------*)
-
- i := i - start_offset;
-
- IF tnc_registers.CX > i THEN
- data_len := tnc_registers.CX - i
- ELSE
- data_len := 0;
-
- (*-----------------------------------------------------------------------*)
- (* If thats all the data then we are done *)
- (*-----------------------------------------------------------------------*)
-
- IF (data_len < 1) THEN
- BEGIN;
- data_place.data_ptr^.long_length :=
- LENGTH(data_place.data_ptr^.str_data);
- EXIT;
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Tack the data on the end of the message *)
- (*-----------------------------------------------------------------------*)
-
- STR(data_len, cvt_string);
- data_place.data_ptr^.str_data := data_place.data_ptr^.str_data
- + ' len ' + cvt_string + cr;
-
- i := LENGTH(data_place.data_ptr^.str_data);
-
- MOVE(data_ptr^, data_place.data_ptr^.str_data[i+1], data_len);
-
- INC(data_len, i);
-
- IF data_len >= 255 THEN
- data_place.data_ptr^.str_data[0] := CHR(255)
- ELSE
- data_place.data_ptr^.str_data[0] := CHR(data_len);
-
- data_place.data_ptr^.long_length := data_len;
-
- END; (*----- End monitor print procedure ----------------------------*)